package com.lframework.xingyun.sc.util;



import cn.hutool.core.util.IdUtil;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author zhoujh
 * @Description
 * @Date 2022/8/26 10:20
 */
@Data
@Slf4j
@Component
public class MinioUtil {

    //minio服务地址，需要配置成 http://IP:端口  若不配置http协议，则默认会是https
    @Value("${minio.server}")
    private String minioServer;
    //认证用户名
    @Value("${minio.username}")
    private String username;
    //认证密码
    @Value("${minio.password}")
    private String password;

    //全局客户端，由于客户端是http请求的  所以使用完client后不需要关闭
    private MinioClient minioClient;

    private MinioClient getMinioClient() {
        if (Objects.nonNull(minioClient)) {
            return minioClient;
        } else {
            minioClient = MinioClient.builder().endpoint(minioServer).credentials(username, password).build();
        }
        return minioClient;
    }

    /**
     * 创建bucket
     *
     * @param bucketName
     * @return
     */
    public boolean createBucket(String bucketName) {
        boolean isCreated = false;
        try {
            boolean isExist = getMinioClient().bucketExists(BucketExistsArgs.builder().bucket(bucketName.toLowerCase()).build());
            if (!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName.toLowerCase()).build());
                isCreated = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isCreated;
    }

    /**
     * 上传文件
     *
     * @param bucket
     * @param filePath
     * @return
     * @throws Exception
     */
    public String uploadFile(String bucket, String filePath) throws Exception {
        File file = new File(filePath);
        String fileName = file.getName();
        String newFileName = IdUtil.fastSimpleUUID() + fileName.substring(fileName.indexOf("."));
        log.info("文件名称：" + fileName);
        getMinioClient().uploadObject(UploadObjectArgs.builder()
                .bucket(bucket).object(newFileName).filename(filePath).build()).toString();
        return getObjectPrefixUrl(bucket) + newFileName;
    }

    /**
     * 文件url前半段
     *
     * @param bucket 桶
     * @return 前半段
     */
    private String getObjectPrefixUrl(String bucket) {
        return String.format("%s/%s/", minioServer, bucket);
    }

    /**
     * 流式上传文件
     *
     * @param bucket      桶
     * @param fileName    文件名称，包含后缀名
     * @param inputStream 文件输入流
     * @return 文件url
     */
    public String uploadInputStream(String bucket, String fileName, InputStream inputStream) throws Exception {
        MinioClient client = getMinioClient();
        client.putObject(PutObjectArgs.builder().bucket(bucket).object(fileName).stream(inputStream, inputStream.available(), -1).build());
        return getObjectPrefixUrl(bucket) + fileName;
    }

    /**
     * 下载文件
     *
     * @param bucket   桶
     * @param fileName 文件名称
     * @return 文件流
     */
    public InputStream download(String bucket, String fileName) throws Exception {
        MinioClient client = getMinioClient();
        return client.getObject(GetObjectArgs.builder().bucket(bucket).object(fileName).build());
    }

    /**
     * 删除文件
     *
     * @param bucket   桶
     * @param fileName 文件名称
     */
    public void deleteFile(String bucket, String fileName) throws Exception {
        MinioClient client = getMinioClient();
        client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(fileName).build());
    }

    /**
     * 有权限限制的文件预览，
     *
     * @param bucket   桶
     * @param fileName 文件名称
     * @param expires  签名有效时间  单位秒
     * @return 文件签名地址
     */
    public String getSignedUrl(String bucket, String fileName, int expires) throws Exception {
        MinioClient client = getMinioClient();
        return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucket).object(fileName).expiry(expires).build());
    }

    /**
     * 查询所有Bucket列表
     * @return
     * @throws Exception
     */
    public List<Bucket> listBuckets() throws Exception{
        MinioClient client = getMinioClient();
        return client.listBuckets();
    }
}
